package com.droid.mvvmlib.base;

import android.app.Application;
import android.content.Intent;
import android.os.Bundle;

import com.droid.mvvmlib.databinding.SingleLiveEvent;
import com.droid.mvvmlib.router.IRouterCallBack;

import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * ViewModel 基类
 *
 * @author zyc0617
 * @since  2019/7/4 10:11
 */
public class UiChangeViewModel<M extends BaseModel, D> extends AndroidViewModel implements IBaseViewModel, Consumer<Disposable> {

    protected M model;
    private final UiChangeLiveData mUiChangeLiveData;

    public final MutableLiveData<ViewStatus> viewStatus = new MutableLiveData<>();
    public final MutableLiveData<String> errorMessage = new MutableLiveData<>();

    //管理RxJava，主要针对RxJava异步操作造成的内存泄漏
    private CompositeDisposable mCompositeDisposable;

    public void tryToRefresh() {
        if (model != null) {
            model.refresh();
        }
    }

    public UiChangeViewModel(@NonNull Application application) {
        this(application, null);
    }

    public UiChangeViewModel(@NonNull Application application, M model) {
        super(application);
        this.model = model;
        mUiChangeLiveData = new UiChangeLiveData();
        viewStatus.setValue(ViewStatus.LOADING);
        errorMessage.setValue("");
    }

    protected void addSubscribe(Disposable disposable) {
        if (disposable == null) {
            return;
        }
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeDisposable();
        }
        mCompositeDisposable.add(disposable);
    }

    public UiChangeLiveData getUiChangeLiveData() {
        return mUiChangeLiveData;
    }

    public void showDialog(SuperBaseDialog dialog) {
        mUiChangeLiveData.getShowDialogEvent().postValue(dialog);
    }

    public void dismissDialog(SuperBaseDialog dialog) {
        mUiChangeLiveData.getDismissDialogEvent().postValue(dialog);
    }

    public void dismissDialog() {
        SuperBaseDialog baseDialog = mUiChangeLiveData.getShowDialogEvent().getValue();
        if (baseDialog != null && baseDialog.isShowing()) {
            dismissDialog(baseDialog);
        }
    }

    public void startActivity(String path) {
        startActivity(path, null);
    }

    public void startActivity(String path, int flag) {
        startActivity(path, null, flag, -1, null);
    }

    public void startActivity(String path, int flag, IRouterCallBack callBack) {
        startActivity(path, null, flag, -1, callBack);
    }

    public <T> void startActivity(String path, Bundle bundle) {
        startActivity(path, bundle, null);
    }

    public <T> void startActivity(String path,  Bundle bundle, IRouterCallBack callback) {
        startActivity(path, bundle, -1, null);
    }

    public <T> void startActivity(String path, Bundle bundle, int flag, IRouterCallBack callback) {
        startActivity(path, bundle, flag, -1, callback);
    }

    public <T> void startActivity(String path, Bundle bundle,int reqCode) {
        startActivity(path, bundle, -1, reqCode, null);
    }

    public <T> void startActivity(String path, Bundle bundle, int flag, int reqCode, IRouterCallBack callback) {
        mUiChangeLiveData.getStartActivityEvent().postValue(new StartActivityParams(path, bundle, flag, reqCode, callback));
    }

    public void finishAndExitApplication() {
        mUiChangeLiveData.getFinishAndExitApplicationEvent().call();
    }

    public void finishActivity(Intent intent) {
        mUiChangeLiveData.getFinishActivityEvent().postValue(intent);
    }

    public void finishActivity() {
        finishActivity(null);
    }

    @Override
    public void onAny(LifecycleOwner owner, Lifecycle.Event event) {

    }

    @Override
    public void onCreate() {

    }

    @Override
    public void onDestroy() {

    }

    @Override
    public void onStart() {

    }

    @Override
    public void onStop() {

    }

    @Override
    public void onResume() {

    }

    @Override
    public void onPause() {

    }

    @Override
    public void accept(Disposable disposable) throws Exception {
        addSubscribe(disposable);
    }

    @Override
    protected void onCleared() {
        super.onCleared();
        //ViewModel销毁时会执行，同时清除Model
        if (model != null) {
            model.cancel();
        }

        //ViewModel销毁时会执行，同时取消所有异步任务
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
    }

    public static class UiChangeLiveData {
        private SingleLiveEvent<SuperBaseDialog> mShowDialogEvent;
        private SingleLiveEvent<SuperBaseDialog> mDismissDialogEvent;
        private SingleLiveEvent<StartActivityParams> mStartActivityEvent;
        private SingleLiveEvent<Boolean> mFinishAndExitApplication;

        private SingleLiveEvent<Boolean> mOnBackPressedEvent;

        private SingleLiveEvent<Intent> mFinishActivityEvent;

        public SingleLiveEvent<SuperBaseDialog> getShowDialogEvent() {
            return mShowDialogEvent = createLiveData(mShowDialogEvent);
        }

        public SingleLiveEvent<SuperBaseDialog> getDismissDialogEvent() {
            return mDismissDialogEvent = createLiveData(mDismissDialogEvent);
        }

        public SingleLiveEvent<StartActivityParams> getStartActivityEvent() {
            return mStartActivityEvent = createLiveData(mStartActivityEvent);
        }

        public SingleLiveEvent<Boolean> getFinishAndExitApplicationEvent() {
            return mFinishAndExitApplication = createLiveData(mFinishAndExitApplication);
        }

        public SingleLiveEvent<Boolean> getOnBackPressedEvent() {
            return mOnBackPressedEvent = createLiveData(mOnBackPressedEvent);
        }

        public SingleLiveEvent<Intent> getFinishActivityEvent() {
            return mFinishActivityEvent = createLiveData(mFinishActivityEvent);
        }

        private SingleLiveEvent createLiveData(SingleLiveEvent liveData) {
            if (liveData == null) {
                liveData = new SingleLiveEvent();
            }
            return liveData;
        }
    }

    public static class StartActivityParams<T> {
        private String path;
        private Bundle bundle;
        private int flag;
        private int reqCode;
        private IRouterCallBack callback;

        public StartActivityParams(String path, Bundle bundle, int flag) {
            this(path, bundle, flag, null);
        }

        public StartActivityParams(String path, Bundle bundle, int flag, IRouterCallBack callback) {
            this(path, bundle, flag, 0, callback);
        }

        public StartActivityParams(String path, Bundle bundle, int flag, int reqCode, IRouterCallBack callback) {
            this.path = path;
            this.bundle = bundle;
            this.flag = flag;
            this.reqCode = reqCode;
            this.callback = callback;
        }

        public String getPath() {
            return path;
        }

        public void setPath(String path) {
            this.path = path;
        }

        public Bundle getBundle() {
            return bundle;
        }

        public void setBundle(Bundle bundle) {
            this.bundle = bundle;
        }

        public int getFlag() {
            return flag;
        }

        public void setFlag(int flag) {
            this.flag = flag;
        }

        public int getReqCode() {
            return reqCode;
        }

        public void setReqCode(int reqCode) {
            this.reqCode = reqCode;
        }

        public IRouterCallBack getCallback() {
            return callback;
        }

        public void setCallback(IRouterCallBack callback) {
            this.callback = callback;
        }
    }
}
